ESP32 BLE + Android + Arduino IDE = AWESOME : 5 Steps (with Pictures) 您所在的位置:网站首页 arduino ide esp32ble notify ESP32 BLE + Android + Arduino IDE = AWESOME : 5 Steps (with Pictures)

ESP32 BLE + Android + Arduino IDE = AWESOME : 5 Steps (with Pictures)

2024-07-14 00:09| 来源: 网络整理| 查看: 265

First load the example sketch I attached a few steps ago and I'll try to give a brief explanation of what's happening. If you're using a different ESP32 dev board you should make sure that the LED pin is initialized correctly. Note that in Arduino IDE you should write the GPIO number, not necessarily the pin number shown on the board's pinout diagram.

BLE Intro

Bluetooth Low Energy (BLE) is a slightly different protocol than the traditional Bluetooth we might find in things like Bluetooth audio, for example. Instead of constantly streaming data, BLE "servers" (like the ESP32 reading sensor data) can "notify" clients (like your smartphone) periodically to send them bits of data. Therefore, BLE is more suitable for low-power IoT applications where large amounts of data aren't required.

Now in order to know which server and client to connect to, both the server and clients use a "service UUID" which describes the overarching service (kind of like a grocery store, Walmart for example). Inside this service there can be several "characteristics" which are defined by characteristic UUID's. This can be thought of kind of like the snack section in the Walmart, or the canned food section. Then we have "descriptors", which are attributes of the characteristics describing what it's being used for, and can be thought of like the brand of potato chips in the snack aisle of Walmart. This allows interoperability and standardization between various BLE devices so that you can, for example, connect your ESP32 with a heart rate monitor like what Andreas Spiess does in this YouTube video. You can view some example descriptors here.

So to summarize, when you (the client) check out Walmart (the service) you might be looking for potato chips (the characteristic) and pick up some Pringles (the descriptor). Because the product is labeled "Pringles" and not "Great Value" you know which product to choose from and what to expect. This is sort of how BLE devices operate. In our example, we use two different characteristics, TX and RX under the overarching "service" to send data to and receive data from a client (Android device) via these two channels. The ESP32 (acting as the server) "notifies" the client via the TX characteristic UUID and data is sent to the ESP32 and received via the RX characteristic UUID. However, since there is sending and receiving, TX on the ESP32 is actually RX on the Android app, so inside Thunkable you will notice that the UUID's are swapped from those in the Arduino sketch.

Arduino Code Explained

In this section I'll point out a few important things. At the top of the sketch we include the necessary libraries for the code to run:

#include #include #include #include

Thankfully these libraries were bestowed upon us by Neil Kolban (thanks again!) and are now included in the ESP32 package distribution by default.

Also near the top of the sketch we define the analog read pin as well as the LED pin. Note that it's the GPIO pin number and not necessarily other pin numbers you see on Google.

const int readPin = 32; // Use GPIO number. See ESP32 board pinoutsconst int LED = 2; // Could be different depending on the dev board. I used the DOIT ESP32 dev board.

Next, we define the service and characteristic UUID's for both TX and RX (two-way communication):

#define SERVICE_UUID "6E400001-B5A3-F393-E0A9-E50E24DCCA9E" // UART service UUID#define CHARACTERISTIC_UUID_RX "6E400002-B5A3-F393-E0A9-E50E24DCCA9E" #define CHARACTERISTIC_UUID_TX "6E400003-B5A3-F393-E0A9-E50E24DCCA9E"

Because what's transmitted on one end is received on the other and vice versa, the RX UUID in the *app* is the TX UUID for the *ESP32* and vice versa. Next let's look at the callback function that handles the Bluetooth connection status:

class MyServerCallbacks: public BLEServerCallbacks { void onConnect(BLEServer* pServer) { deviceConnected = true; }; void onDisconnect(BLEServer* pServer) { deviceConnected = false; } };

All this does is set the "deviceConnected" flag true or false when you connect or disconnect from the ESP32. Similarly there's another callback function that handles receiving data being sent from the client (phone):

class MyCallbacks: public BLECharacteristicCallbacks { void onWrite(BLECharacteristic *pCharacteristic) { std::string rxValue = pCharacteristic->getValue();

if (rxValue.length() > 0) { Serial.println("*********"); Serial.print("Received Value: ");

for (int i = 0; i < rxValue.length(); i++) { Serial.print(rxValue[i]); }

Serial.println();

// Do stuff based on the command received from the app if (rxValue[0] == '1') { Serial.print("Turning ON!"); digitalWrite(LED, HIGH); } else if (rxValue.find("B") != -1) { Serial.print("Turning OFF!"); digitalWrite(LED, LOW); }

Serial.println(); Serial.println("*********"); } } };

I've added an "if" statement at the end that toggles the LED on or off depending on what letter is sent by the app. Now let's have a look at the setup() function. As usual, we set up Serial and set the LED pin to OUTPUT but then we also initialize the ESP32 as a BLE device and set its name:

// Create the BLE DeviceBLEDevice::init("ESP32 UART Test"); // Give it a name

Next, we create the BLE server,

// Create the BLE Server BLEServer *pServer = BLEDevice::createServer(); pServer->setCallbacks(new MyServerCallbacks());

create a BLE service using the service UUID,

// Create the BLE ServiceBLEService *pService = pServer->createService(SERVICE_UUID);

and add the characteristics

// Create a BLE CharacteristicpCharacteristic = pService->createCharacteristic( CHARACTERISTIC_UUID_TX, BLECharacteristic::PROPERTY_NOTIFY ); pCharacteristic->addDescriptor(new BLE2902()); BLECharacteristic *pCharacteristic = pService->createCharacteristic( CHARACTERISTIC_UUID_RX, BLECharacteristic::PROPERTY_WRITE ); pCharacteristic->setCallbacks(new MyCallbacks());

According to Andreas Spiess' video, here the BLE2902 descriptor makes it so that the ESP32 won't notify the client unless the client wants to open its ears up to read the values to eliminate "talking to the air" and we also set the callback that handles receiving values via the RX channel. However, if you try uncommenting the BLE2902 line and even the BLE2902 #include line, the code still seems to run just as it did before! Maybe someone more knowledgeable can tell us what's going on here! Next, we start the BLE service and start advertising, but the ESP32 ain't gonna send nothin' until a client connects!

// Start the servicepService->start();// Start advertising pServer->getAdvertising()->start(); Serial.println("Waiting a client connection to notify...");

Now let's take a look at the loop() function. Here we check if the device is connected or not (handled by the callback function), and if so, we continue to read a sensor value (for now it's just a random analog reading), convert it to a char array using "dtostrf" so that the app can process it, set the value to send, and notify the client!

void loop() { if (deviceConnected) { // Fabricate some arbitrary junk for now... txValue = analogRead(readPin) / 3.456; // This could be an actual sensor reading! // Let's convert the value to a char array: char txString[8]; // make sure this is big enuffz dtostrf(txValue, 1, 2, txString); // float_val, min_width, digits_after_decimal, char_buffer // pCharacteristic->setValue(&txValue, 1); // To send the integer value // pCharacteristic->setValue("Hello!"); // Sending a test message pCharacteristic->setValue(txString); pCharacteristic->notify(); // Send the value to the app! Serial.print("*** Sent Value: "); Serial.print(txString); Serial.println(" ***"); } delay(1000); }

Upload the Sketch!

Now upload the sketch to your ESP32 board, making sure that you have the right board and COM port selected. When it's done, open the serial monitor under Tools / Serial Monitor and you should see "Waiting a client connection to notify..." Now open the Android app, click the "Connect" button at the top left, and you should see a list of available nearby devices. Select the ESP32 and you should see the button text change to "Connected!" and start seeing values on the screen. To toggle the LED on or off press the "LED" button and check the serial monitor to see how it sends "A" or "B" to the ESP32. Pretty neat stuff huh?

Sending Multiple Values

A lot of people have asked this question: "how do I send multiple values to and from the ESP32 and app?" That's a good question, and luckily it's not hard at all! The easiest way I've found is to simply send the values in comma-separated variable (CSV) format. For example, if you're measuring temperature and humidity and you measured 21 *C and 55% humidity and want to send it to the app, simply program the ESP32 to send "21,55" and the app can parse it easily.

Sending Lots of Data

Unfortunately BLE isn't really meant for large streams of data (that's more for traditional Bluetooth, like those used in audio-streaming devices). The max allowable data size per packet is 20 bytes for BLE specification, so if you want to send anything more you'll have to split it up into multiple packets. Fortunately this is not that hard to do either. Simply use a delimiter like "*" or "!" or something unique at the end of your entire message to let the app know the message is complete and to start listening for a new message. For example, if you want to send and and cumulatively + > 20 bytes, then what you can do is send then proceed with the next message if needed.



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有